package ar.com.profertil.santander.analizer;

import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;

import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import ar.com.profertil.santander.entity.DetalleEnvio;
import ar.com.profertil.santander.entity.HeaderEnvio;
import ar.com.profertil.santander.entity.TrailerEnvio;

// TODO: Auto-generated Javadoc
/**
 * The Class AnalizerEnvioDeuda.
 *
 * @author augusto.ferrari@softtek.com
 * 
 * Esta clase presenta metodos para recuperar las diferentes estructuras del archivo de entrada.
 */
public class AnalizerEnvioDeuda implements Serializable {

	/** The Constant serialVersionUID. */
	private static final long serialVersionUID = -2817426977536742390L;

	/** The header. */
	private HeaderEnvio header;
	
	/** The detalle. */
	private DetalleEnvio[] detalle;
	
	/** The trailer. */
	private TrailerEnvio trailer;
	
	/**
	 * Inicializar.
	 *
	 * @param cabecera the cabecera
	 * @param detalles the detalles
	 * @param cierre the cierre
	 */
	public void inicializar(String cabecera, 
			  				String[] detalles, 
			  				String cierre) {
		this.header = parsearHeader(cabecera);
		this.detalle = parsearDetalles(detalles);
		this.trailer = parsearTrailer(cierre);
	}

	/**
	 * Gets the header.
	 *
	 * @return the header
	 */
	public HeaderEnvio getHeader() {
		return header;
	}
	
	/**
	 * Gets the detalle.
	 *
	 * @return the detalle
	 */
	public DetalleEnvio[] getDetalle() {
		return detalle;
	}
	
	/**
	 * Gets the trailer.
	 *
	 * @return the trailer
	 */
	public TrailerEnvio getTrailer() {
		return trailer;
	}

	//Metodo para recuperar los atributos del Header.
	/**
	 * Parsear header.
	 *
	 * @param cabecera the cabecera
	 * @return the header envio
	 */
	private HeaderEnvio parsearHeader(String cabecera) {
		
		HeaderEnvio header = new HeaderEnvio();
		
		try {
			//Crear el documento XML.
			Document doc = convertirADom(cabecera);
			NodeList nodos = recuperarNodos(doc, "ZHEADER_SO");
			Node nodo = nodos.item(0);
			
			//Recuperar los datos y llenar el Header.
			if (nodo.getNodeType() == Node.ELEMENT_NODE) {
				
				Element zHeader = (Element) nodo;
				
				header.setTipoDeRegistro(getString(zHeader , "ZTIPOREG"));
				header.setCodigoDeOrganismo(getString(zHeader , "ZCODORG"));
				header.setCodigoDeCanal(getString(zHeader , "ZCODCANAL"));
				header.setNumeroDeEnvio(getString(zHeader , "ZENVIO"));
				header.setUltimaRendicionProcesada(getString(zHeader , "ZULTPROC"));
				header.setMarcaDeActualziacionDeCuentaComercial(getString(zHeader , "ZACTCUENTA"));
				header.setMarcaParaPublicacionOnLine(getString(zHeader , "ZONLINE"));
				header.setRelleno(getString(zHeader , "ZESPACIO"));
			}
		}
		catch(Exception e) {
			e.printStackTrace();
		}
		
		return header;
	}
	
	//Metodo para recuperar los atributos de los detalles.
	/**
	 * Parsear detalles.
	 *
	 * @param detalles the detalles
	 * @return the detalle envio[]
	 */
	private DetalleEnvio[] parsearDetalles(String[] detalles) {
		
		DetalleEnvio[] detalle = new DetalleEnvio[detalles.length];
		
		try {
			//Iterar para cada nodo.
			for (int i = 0; i < detalles.length; i++) {
				
				DetalleEnvio detail = new DetalleEnvio();
				
				//Crear el documento XML.
				Document doc = convertirADom(detalles[i]);
				NodeList nodos = recuperarNodos(doc, "ZDETALLE_SO");
				Node nodo = nodos.item(0);
				
				//Recuperar los datos y llenar el Detalle.
				if (nodo.getNodeType() == Node.ELEMENT_NODE) {
					
					Element zDetalle = (Element) nodo;
					
					detail.setTipoDeRegistro(getString(zDetalle , "ZTIPOREG"));
					detail.setTipoDeOperacion(getString(zDetalle , "ZTIPO_OPER"));
					detail.setCodigoDeMoneda(getString(zDetalle , "ZMONEDA"));
					detail.setNumeroDeCliente(getString(zDetalle , "ZCLIENTE"));
					detail.setTipoDeComprobante(getString(zDetalle , "ZTIPOCOMP"));
					detail.setNumeroDeComprobante(getString(zDetalle , "ZNUMCOMP"));
					detail.setNumeroDeCuota(getString(zDetalle , "ZNUMCUOTA"));
					detail.setNombreDeCliente(getString(zDetalle , "ZNOMBRE"));
					detail.setDireccionDelCliente(getString(zDetalle , "ZDIRECCION"));
					detail.setDescripcionDeLaLocalidad(getString(zDetalle , "ZLOCALIDAD"));
					detail.setPrefijoDelCodigoPostal(getString(zDetalle , "ZPREFCO"));
					detail.setNumeroDelCodigoPostal(getString(zDetalle , "ZCODPOST"));
					detail.setUbicacionManzanaDelCodigoPostal(getString(zDetalle , "ZUBICCO"));
					detail.setFechaDePrimerVencimiento(getString(zDetalle , "ZFVENC1"));
					detail.setImporteAlPrimerVencimiento(getString(zDetalle , "ZIMPORTE1"));
					detail.setFechaDeSegundoVencimiento(getString(zDetalle , "ZFVENC2"));
					detail.setImporteDeSegundoVencimiento(getString(zDetalle , "ZIMPORTE2"));
					detail.setFechaHastaDescuento(getString(zDetalle , "ZFDESC"));
					detail.setImporteProntoPago(getString(zDetalle , "ZIMPORTE_PPAGO"));
					detail.setFechaHastaPunitorios(getString(zDetalle , "ZFPUNITORIOS"));
					detail.setTasaDePunitorios(getString(zDetalle , "ZTASAPUNIT"));
					detail.setMarcaDeExcepcioneCobroDeComisionAlDepositante(getString(zDetalle , "ZEXCCOBRO"));
					detail.setFormasDeCobroPermitidas(getString(zDetalle , "ZCOBROS"));
					detail.setNumeroDeCuitDelCliente(getString(zDetalle , "ZCUIT"));
					detail.setCodigoDeIngresosBrutos(getString(zDetalle , "ZCOD_ING"));
					detail.setCodigoDeCondicionDeIva(getString(zDetalle , "ZCOD_IVA"));
					detail.setCodigoDeConcepto(getString(zDetalle , "ZCONCEPTO"));
					detail.setDescripcionDelCodigo(getString(zDetalle , "ZDESCRIPCION"));
					detail.setObservacionLibrePrimera(getString(zDetalle , "ZOBS1"));
					detail.setObservacionLibreSegunda(getString(zDetalle , "ZOBS2"));
					detail.setObservacionLibreTercera(getString(zDetalle , "ZOBS3"));
					detail.setObservacionLibreCuarta(getString(zDetalle , "ZOBS4"));
					detail.setRelleno(getString(zDetalle , "ZESPACIO"));
					
					detalle[i] = detail;
				}
			}
		}
		catch(Exception e) {
			e.printStackTrace();
		}
		
		return detalle;
	}
	
	//Metodo para recuperar los atributos del Trailer.
	/**
	 * Parsear trailer.
	 *
	 * @param cierre the cierre
	 * @return the trailer envio
	 */
	private TrailerEnvio parsearTrailer(String cierre) {
		
		TrailerEnvio trailer = new TrailerEnvio();
		
		try {
			//Crear el documento XML.
			Document doc = convertirADom(cierre);
			NodeList nodos = recuperarNodos(doc , "ZTRAILER_SO");
			Node nodo = nodos.item(0);
			
			//Recuperar los datos y llenar el Trailer.
			if (nodo.getNodeType() == Node.ELEMENT_NODE) {
				
				Element zTrailer = (Element) nodo;
				
				trailer.setTipoDeRegistro(getString(zTrailer , "ZTIPOREG"));
				trailer.setImporteTotalPrimerVencimiento(getString(zTrailer , "ZIMPORTE_TOT"));
				trailer.setCeros(getString(zTrailer , "ZCEROS"));
				trailer.setCantidadDeRegistrosInformados(getString(zTrailer , "ZCANTREG"));
				trailer.setRelleno(getString(zTrailer , "ZESPACIO"));
			}
		}
		catch(Exception e) {
			e.printStackTrace();
		}
		
		return trailer;
	}
	
	//Metodo para convertir la cadena a documento XML.
	/**
	 * Convertir a dom.
	 *
	 * @param xml the xml
	 * @return the document
	 */
	private Document convertirADom(String xml) {
		
		Document doc = null;
		DOMParser parser = new DOMParser();
		
		try {
			parser.parse(new InputSource(new StringReader(xml)));
			doc = parser.getDocument();
		}
		catch(SAXException e) {
			e.printStackTrace();
		}
		catch(IOException e) {
			e.printStackTrace();
		}
		
		return doc;
	}
	
	//Metodo para recuperar los nodos del documento XML.
	/**
	 * Recuperar nodos.
	 *
	 * @param doc the doc
	 * @param etiqueta the etiqueta
	 * @return the node list
	 */
	private NodeList recuperarNodos(Document doc, String etiqueta) {
		
		NodeList listaNodos = doc.getElementsByTagName(etiqueta);
		
		return listaNodos;
	}
	
	//Metodo para recuperar los elementos de un nodo.
	/**
	 * Recuperar elementos.
	 *
	 * @param elemento the elemento
	 * @param etiqueta the etiqueta
	 * @return the node list
	 */
	private NodeList recuperarElementos(Element elemento, String etiqueta) {
		
		NodeList elementos = elemento.getElementsByTagName(etiqueta);
		
		return elementos;
	}
	
	//Metodo para recuperar el valor de una etiqueta.
	/**
	 * Gets the string.
	 *
	 * @param elemento the elemento
	 * @param etiqueta the etiqueta
	 * @return the string
	 */
	private String getString(Element elemento, String etiqueta) {
		String result = "";
		NodeList hijos;
		Element element;
		
		NodeList nodosDentro = recuperarElementos(elemento, etiqueta);
		element = (Element) nodosDentro.item(0);
		if(element != null ){
			hijos = element.getChildNodes();
			if(hijos!= null && hijos.getLength()>0){
				result = hijos.item(0).getNodeValue();
			}
		}
		return result;
	}

}
